﻿using System;
using System.Linq;
using System.Threading.Tasks;
using System.Transactions;
using WalkingTec.Mvvm.Core;
using HengTong.Model.Db;
using HengTong.Model.Db.Other;
using HengTong.Model.Db.Other.Bill;
using HengTong.Model.Services;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using TiaoTaoHelper.Models;
using TiaoTaoHelper.Wtm.Interfaces;
using TiaoTaoHelper.Wtm.Models;
using UUIDNext;

namespace HengTong.ViewModel.Visitor.SysVisitorRecordRequestBillVms
{
    public partial class SysVisitorRecordRequestBillVm : CrudVm<SysVisitorRecordRequestBill>
    {
        public SysVisitorRecordRequestBillVm()
        {
            SetInclude(x => x.VisitorReason);
            SetInclude(x => x.User);
            SetInclude(x => x.Group);
        }

        protected override void InitVM()
        {
        }

        public override async Task DoAddAsync()
        {
            // 查询数据库验证事由是否有效
            var reason = await DC.Set<SysVisitorReason>()
                .AsNoTracking()
                .FirstOrDefaultAsync(e => e.ID == Entity.VisitorReasonId);
            if (!reason.IsActive)
            {
                MSD.AddModelError("", "所选事由无效，请选择其他事由！");
                return;
            }

            //查询访客信息表是否有当前用户的访客记录
            var existingVisitor = await DC.Set<SysVisitorInformation>()
                .AsNoTracking()
                .FirstOrDefaultAsync(v => v.UserId == Guid.Parse(Wtm.LoginUserInfo!.UserId));
            // 判断是否是黑名单
            if (existingVisitor != null && existingVisitor.BlackStatus)
            {
                MSD.AddModelError("", "当前用户已被列入黑名单，无法提交访客申请！");
                return;
            }

            var transaction = await DC.Database.BeginTransactionAsync();
            try
            {
                if (Entity is IBill bill)
                {
                    Entity.BillStatus = BillStatus.草稿;
                    Entity.WorkflowStatus = WorkflowStatus.待提交;
                    var result = await GenerateCodeAsync();
                    if (result.Code == 200)
                    {
                        Entity.BillCode = result.Data;
                    }
                    else
                    {
                        MSD.AddModelError(" ", $"生成编码异常. {result.Message}");
                        return;
                    }
                }

                Entity.ID = Uuid.NewDatabaseFriendly(Database.SqlServer);
                if (Entity is IBasePoco poco)
                {
                    poco.CreateBy = Wtm.LoginUserInfo?.ITCode;
                    poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                    poco.CreateTime = DateTime.Now;
                    poco.UpdateTime = DateTime.Now;
                    Entity.UserId = Guid.Parse(Wtm.LoginUserInfo!.UserId);
                }

                await base.DoAddAsync();


                if (existingVisitor == null)
                {
                    // 如果没有，则创建新的访客信息
                    var newVisitor = new SysVisitorInformation
                    {
                        Name = Entity.Name,
                        Phone = Entity.Phone,
                        IdCardNo = Entity.IdCardNo,
                        IdCardFrontPhotoId = Entity.IdCardFrontPhotoId,
                        IdCardBackPhotoId = Entity.IdCardBackPhotoId,
                        Company = Entity.Company,
                        CarNo = Entity.CarNo,
                        UserId = Entity.UserId,
                    };
                    DC.Set<SysVisitorInformation>().Add(newVisitor);
                    await DC.SaveChangesAsync();
                }
                else
                {
                    // 如果存在，则更新访客信息
                    await DC.Set<SysVisitorInformation>().Where(v => v.UserId == existingVisitor.UserId)
                        .ExecuteUpdateAsync(v => v
                            .SetProperty(x => x.Name, Entity.Name)
                            .SetProperty(x => x.Phone, Entity.Phone)
                            .SetProperty(x => x.IdCardNo, Entity.IdCardNo)
                            .SetProperty(x => x.IdCardFrontPhotoId, Entity.IdCardFrontPhotoId)
                            .SetProperty(x => x.IdCardBackPhotoId, Entity.IdCardBackPhotoId)
                            .SetProperty(x => x.Company, Entity.Company)
                            .SetProperty(x => x.CarNo, Entity.CarNo));
                    await DC.SaveChangesAsync();
                }

                // 提交事务
                await transaction.CommitAsync();
            }
            catch (Exception e)
            {
                await transaction.RollbackAsync();
                MSD.AddModelError(" ", $"信息删除异常{e.Message}");
            }
            finally
            {
                await transaction.DisposeAsync();
            }
        }

        public override async Task DoEditAsync(bool updateAllFields = false)
        {
            if (Entity is IBill { WorkflowStatus: WorkflowStatus.提交中 })
            {
                var raw = await DC.Set<SysVisitorRecordRequestBill>()
                    .AsNoTracking()
                    .FirstOrDefaultAsync(e => e.ID == Entity.ID);
                if (raw.WorkflowStatus != WorkflowStatus.待提交)
                {
                    MSD.AddModelError(" ", "单据已提交审核,请勿重复提交.");
                    return;
                }

                var result = await StartWorkflowAsync("访客申请流程");
                if (result == null) return;
                if (!result.Executed)
                {
                    MSD.AddModelError(" ", $"提交审核异常. {result.Exception?.Message}");
                    return;
                }

                Entity.BillStatus = BillStatus.正文;
                Entity.WorkflowStatus = WorkflowStatus.审核中;
            }

            if (Entity is IBasePoco poco)
            {
                poco.UpdateBy = Wtm.LoginUserInfo?.ITCode;
                poco.UpdateTime = DateTime.Now;
            }

            await base.DoEditAsync(updateAllFields);
        }

        /// <summary>
        /// 必须使用异步事务, 否则工作流引擎会和当前事务冲突
        /// </summary>
        /// <param name="upAllFields"></param>
        public async Task ApproveAsync(bool upAllFields = false)
        {
            using var transactionScope = new TransactionScope(
                TransactionScopeOption.Required,
                new TransactionOptions
                {
                    IsolationLevel = IsolationLevel.ReadCommitted,
                    Timeout = TimeSpan.FromMinutes(10) // 增加超时时间到10分钟
                },
                TransactionScopeAsyncFlowOption.Enabled);
            try
            {
                if (Entity.BillStatus == BillStatus.草稿) Entity.BillStatus = BillStatus.正文;
                Entity.Approver = Wtm.LoginUserInfo?.ITCode;
                Entity.ApprovalTime = DateTime.Now;
                await base.DoEditAsync(upAllFields);
                if (MSD.IsValid)
                {
                    var result = await ContinueWorkflowAsync(ActionName, Remark, "访客申请流程");
                    if (result.Executed == true)
                    {
                        transactionScope.Complete(); // 提交事务
                    }
                    else
                    {
                        MSD.AddModelError(" ", $"工作流执行失败");
                    }
                }
                // 如果到这里，事务会自动回滚
            }
            catch (Exception e)
            {
                // TransactionScope会自动回滚，无需手动操作
                MSD.AddModelError(" ", $"审批操作异常: {e.Message}");
            }
        }

        /// <summary>
        /// 生成编码
        /// </summary>
        /// <returns></returns>
        public async Task<Result<string>> GenerateCodeAsync()
        {
            if (Entity is IBill bill)
            {
                var scope = Wtm.ServiceProvider.CreateScope();
                var service = scope.ServiceProvider.GetRequiredService<CodeGeneratorService>();
                var code = await service.GenerateCodeAsync(Entity.GetType().Name);
                return new Result<string>()
                {
                    Data = code
                };
            }

            return new Result<string>("实体未实现IBill接口");
        }

        /// <summary>
        /// 预测编码
        /// </summary>
        /// <returns></returns>
        public async Task<Result<string>> PredictCodeAsync()
        {
            if (Entity is IBill bill)
            {
                var scope = Wtm.ServiceProvider.CreateScope();
                var service = scope.ServiceProvider.GetRequiredService<CodeGeneratorService>();
                var code = await service.PreviewNextCodeAsync(Entity.GetType().Name);
                return new Result<string>()
                {
                    Data = code
                };
            }

            return new Result<string>("实体未实现IBill接口");
        }

        public override void DoDelete()
        {
            base.DoDelete();
        }
    }
}